package com.chenyanqing.model.two.factory;

import com.chenyanqing.model.two.annotation.Transactional;
import com.chenyanqing.model.two.utils.TransactionalManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TransactionAnnotationProxyFactory implements ProxyFactory{

    private static Logger logger = LoggerFactory.getLogger(TransactionAnnotationProxyFactory.class);

    /**
     * 构造方法私有化
     */
    private TransactionAnnotationProxyFactory(){

    }

    private static  TransactionAnnotationProxyFactory factory = new TransactionAnnotationProxyFactory();

    public static TransactionAnnotationProxyFactory getInstance(){
        return factory;
    }

    /**
     * Object object：委托对象
     * @return  返回代理对象
     */
    @Override
    public Object getJDKProxy(Object object){
        logger.info("Transactional annotation:生成事务管理代理对象,class={}",object.getClass().getName());

       Object proxyInstance =  Proxy.newProxyInstance(object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Transactional annotation = method.getAnnotation(Transactional.class);
                        logger.info("method:{},annotation:{}",method.getName(),annotation);
                        if(annotation==null){
                            return method.invoke(object,args);
                        }
                        else {
                            logger.info("Transactional annotation:事务注解切面逻辑执行,method:{}",method);
                            //开启事务
                            TransactionalManager.getInstance().beginTransaction();
                            Object result = null;
                            try {
                                result = method.invoke(object, args);
                                //提交事务
                                TransactionalManager.getInstance().commit();
                                //方法执行之后的增强
                                return result;
                            } catch (Exception e) {
                                TransactionalManager.getInstance().rollback();
                                throw e;
                            }

                        }


                    }
                });

        logger.info("Transactional annotation:生成事务管理代理对象后,返回值class={}",proxyInstance.getClass().getName());
        return proxyInstance;
    }

}
